/**
 *	QuebraLink - Quebrador de links que tem protetor
 *  Copyright (C) 2011  Ranis <ranishot@gmail.com>
 * 
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 *  Classe de Algoritmos
 *
 *	Esta Classe define toda operação de algoritmos do projeto QuebraLink
 *
 *	@package QuebraLink
 *	@name QuebraLink.java
 *	@author	Ranishot <ranishot@gmail.com>
 *	@copyright (C)2010 - 2011 Ranishot.
 *	@contributors Rodrigo Borges <rodrigo@rbmsoft.com.br>
 *	@license GNU GPL v3
 *	@version 3.5
 *	@since 14/06/2011
 */
//@TODO Criar arquivo dlc(formato do JDownloader)com os links quebrados e tbem multiplos links
package quebralink;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import sun.misc.BASE64Decoder;
// observação: colocar mais comentários para especificar partes do código

/**
 *
 * @author ranishot
 */
// @TODO: colocar mais comentários para especificar partes do código
//TODO http://pegaki.com/redirect/download2/index.php?id=YUhSMGNEb3ZMM2QzZHk1bWFXeGxjMlZ5ZG1VdVkyOXRMMlpwYkdVdllVRTVWWEJUTXc9PQ==
public class QuebraLink {

    private static String validLink = null;
    /*
    public static void main(String[] args) {
    QuebraLink a = new QuebraLink();
    //  a.quebraLink("http://www.rededownload.com/download-microsoft-visio-2003/");
    //  System.out.println(a.quebraLink("http://www.rededownload.com/download-microsoft-visio-2003/"));
    }
     * 
     */

    public String quebraLink(String link) throws StringIndexOutOfBoundsException {
//================================================================================
        // Declaração de variaveis
        link = link.replace(".url", "");
        int cod = 0;
        final String linkInit = link.replace("#", "");
        boolean estado = false;
        char letra;
        String linkOrig;
        String newlink = "";
        linkOrig = link.replace("#", "");
        linkOrig = linkOrig.replace(".url", "");
        linkOrig = linkOrig.replace(".html", "");
        linkOrig = linkOrig.replace("http://", "");

        /* @TODO criar uma nova condicional aqui pra testar as URL que não tem ? e id= ou url= por enquanto,
         * caso não tenha procurar por http ou ptth na URL a partir do 7 indice da String
         * tentar descobrir como achar o fim da url invertida nesse caso que não tem um delimitador(= ou ?)
         * http://www.cdscompletos.org/out/lmth.rar.9ogoFPFP/0020cmhqt7df/moc.noro//:ptth se tiver .html
         * invertido fica facil pra achar mas se não tiver hum...! tenho que pensar nisso !
         */
//==================================================================================
        //clube do download
        if (linkOrig.contains("clubedodownload")) {
            for (int i = 7; i < linkInit.length(); i++) {
                if (linkOrig.charAt(i) == '/') {
                    for (int j = i + 1; j < linkOrig.length(); j++) {
                        newlink += linkOrig.charAt(j);
                    }
                    if (newlink.contains("//:ptth")) {
                        newlink = inverteFrase(newlink);
                        if (isValid(newlink)) {
                            return newlink;
                        }
                    } else if (newlink.contains("http://")) {
                        if (isValid(newlink)) {
                            return newlink;
                        }
                    } else {
                        break;
                    }
                }

            }
        }
//==================================================================================        
        //http://protetordelink.tv/download/mvdownloads/1/687474703a2f2f7777772e6d65676175706c6f61642e636f6d2f3f643d303949454a345335
        if (linkOrig.contains("protetordelink.tv")) {
            for (int i = linkOrig.length() - 1; i >= 0; i--) {
                letra = linkOrig.charAt(i);
                if (letra == '/') {
                    for (int j = i + 1; j < linkOrig.length(); j++) {
                        newlink += linkOrig.charAt(j);
                    }
                    newlink = HexToChar(newlink);
                    if (newlink.contains("ptth")) {
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            newlink = inverteFrase(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            newlink = inverteFrase(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    } else {
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    }
                }

            }

        }


//==================================================================================
        //

        if (linkOrig.contains("baixeaquifilmes")) {

            for (int i = 0; i < linkOrig.length(); i++) {
                letra = linkOrig.charAt(i);
                if (letra == '?') {
                    for (int j = i + 1; j < linkOrig.length(); j++) {
                        newlink += linkOrig.charAt(j);

                    }

                    if (newlink.contains(":ptth")) {
                        newlink = inverteFrase(newlink);
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    } else {
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    }

                }

            }

        }

//=================================================================================
        // 1º Parte

        if (linkOrig.contains("downloadsgratis")) {// 1º if externo
            for (int i = 0; i < linkOrig.length(); i++) {//1º for interno
                letra = linkOrig.charAt(i);

                if (letra == '!') {//2º if interno
                    for (int j = i + 1; j < linkOrig.length(); j++) {// 2º for interno
                        newlink += linkOrig.charAt(j);

                    }// fecha 2º for interno

                    if (precisaRepassar(QuebraLink.decode64(newlink))) {
                        newlink = quebraLink(QuebraLink.decode64(newlink));
                        if (isValid(newlink)) {
                            return newlink;
                        }
                    } else {
                        if (isValid(newlink)) {
                            return newlink;
                        }
                    }

                }// fecha 2º if interno

            }//fecha 1º for interno

        }// fecha 1º if externo
//=========================================================================================
        // vinXp tem q ter um metodo especifico "por enquanto"
        newlink = "";
        if (linkOrig.contains("vinxp")) {
            System.out.println("é");
            for (int i = 1; i < linkOrig.length(); i++) {
                if (linkOrig.charAt(i) == '=') {
                    for (int j = i + 1; j < linkOrig.length(); j++) {
                        newlink += linkOrig.charAt(j);
                    }
                    break;
                }
            }

            if (newlink.contains(".vinxp")) {

                newlink = newlink.replace(".vinxp", "");
            }
            newlink = decodeCifraDeCesar(newlink);
            System.out.println(newlink);
            return newlink;

        }


        //@TODO Manter essa parte de cima até versão superior 3.5 pois 
        // esse tipo de link quase não é mais utilizado

//=========================================================================================
        //4º Parte
        if (linkOrig.contains("?")) {// 1º if externo
            String linkTemporary = "";
            newlink = "";
            if (linkOrig.contains("go!")) {
                linkOrig = linkOrig.replace("?go!", "?");

            }


            if (linkOrig.contains("=")) {//2º if interno
                for (int i = 0; i < linkOrig.length(); i++) {// 1º for interno
                    letra = linkOrig.charAt(i);
                    if (letra == '=') {//3º if interno
                        for (int j = i + 1; j < linkOrig.length(); j++) {//2º for interno
                            newlink += linkOrig.charAt(j);

                        }//2º for interno
                        linkTemporary = QuebraLink.decode64(newlink);
                        break;
                    }// fecha 3º if interno

                }//fecha 1º for interno

                if (linkTemporary.contains("http")) {// 4º if interno
                    newlink = "";
                    for (int i = 0; i < linkTemporary.length(); i++) {// 3º for interno
                        letra = linkTemporary.charAt(i);
                        if (letra == 'h') {//5º if interno
                            for (int j = i; j < linkTemporary.length(); j++) {
                                newlink += linkTemporary.charAt(j);
                            }
                            newlink = newlink.replace("!og", "");
                            if (precisaRepassar(newlink)) {
                                newlink = quebraLink(newlink);
                                if (isValid(newlink)) {
                                    return newlink;
                                }
                            } else {
                                if (isValid(newlink)) {
                                    return newlink;
                                }
                            }
                        }//fecha 5º if interno
                    }// fecha 3º for interno
                }// fecha 4º if interno

                if (linkTemporary.contains("ptth")) {//6º if interno
                    newlink = "";
                    linkTemporary = inverteFrase(linkTemporary);
                    for (int i = 0; i < linkTemporary.length(); i++) {//4º for interno
                        letra = linkTemporary.charAt(i);
                        if (letra == 'h') {// 7º if interno
                            for (int j = i; j < linkTemporary.length(); j++) {

                                newlink += linkTemporary.charAt(j);

                            }
                            newlink = newlink.replace("!og", "");
                            if (precisaRepassar(newlink)) {
                                newlink = quebraLink(newlink);
                                if (isValid(newlink)) {
                                    return newlink;
                                }
                            } else {
                                if (isValid(newlink)) {
                                    return newlink;
                                }
                            }
                        }//fecha 7º if interno
                    }//fecha 4º for interno
                }//fecha 6º if interno

            }//fecha 2º if interno

            linkTemporary = "";
            for (int i = 0; i < linkOrig.length(); i++) {// 3º for interno
                letra = linkOrig.charAt(i);

                if (letra == '?') {// 8º if interno
                    for (int j = i + 1; j < linkOrig.length(); j++) {// 5º for interno
                        linkTemporary += linkOrig.charAt(j);
                    }//fecha 5º for interno
                    link = QuebraLink.decode64(linkTemporary);
                    break;
                }//fecha 8º if interno
            }// fecha 3º for interno

            if (link.contains("http")) {// 9º if interno
                newlink = "";
                for (int i = 0; i < link.length(); i++) {//6º for interno
                    letra = link.charAt(i);

                    if (letra == 'h') {// 10º if interno
                        for (int j = i; j < link.length(); j++) {
                            newlink += link.charAt(j);
                        }
                        newlink = newlink.replace("!og", "");
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    }//fecha 10º if interno
                }//fecha 6º for interno
            }// 9º if interno

            if (link.contains("ptth")) {//11º if interno
                newlink = "";
                linkTemporary = inverteFrase(link);

                for (int i = 0; i < linkTemporary.length(); i++) {// 7º for interno
                    letra = linkTemporary.charAt(i);

                    if (letra == 'h') {// 12º if interno

                        for (int j = i; j < linkTemporary.length(); j++) {// 8 for interno

                            newlink += linkTemporary.charAt(j);
                        }//fecha 8 for interno
                        newlink = newlink.replace("!og", "");
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    }//fecha 12º if interno
                }//fecha  7º for interno
            }//fecha 11º if interno;
            linkOrig = linkInit;
            link = linkOrig;
            newlink = "";

        }// fecha 1º if externo
//==================================================================================================
        // 5º Parte -hexa

        if (linkOrig.contains("?")) {// 1º if externo
            String linkTemporary = "";
            newlink = "";
            if (linkOrig.contains("go!")) {
                linkOrig = linkOrig.replace("?go!", "?");

            }


            if (linkOrig.contains("=")) {//2º if interno
                for (int i = 0; i < linkOrig.length(); i++) {// 1º for interno
                    letra = linkOrig.charAt(i);
                    if (letra == '=') {//3º if interno
                        for (int j = i + 1; j < linkOrig.length(); j++) {//2º for interno
                            newlink += linkOrig.charAt(j);

                        }//2º for interno
                        linkTemporary = linkTemporary.replace(".", "");
                        try {
                            linkTemporary = HexToChar(newlink);
                        } catch (Exception e) {
                            System.err.println("erro hex 1º");
                            estado = true;
                        }
                        break;
                    }// fecha 3º if interno

                }//fecha 1º for interno

                if (linkTemporary.contains("http") && !estado) {// 4º if interno
                    newlink = "";
                    for (int i = 0; i < linkTemporary.length(); i++) {// 3º for interno
                        letra = linkTemporary.charAt(i);
                        if (letra == 'h') {//5º if interno
                            for (int j = i; j < linkTemporary.length(); j++) {
                                newlink += linkTemporary.charAt(j);
                            }
                            newlink = newlink.replace("!og", "");
                            if (precisaRepassar(newlink)) {
                                newlink = quebraLink(newlink);
                                if (isValid(newlink)) {
                                    return newlink;
                                }
                            } else {
                                if (isValid(newlink)) {
                                    return newlink;
                                }
                            }
                        }//fecha 5º if interno
                    }// fecha 3º for interno
                }// fecha 4º if interno

                if (linkTemporary.contains("ptth") && !estado) {//6º if interno
                    newlink = "";
                    linkTemporary = inverteFrase(linkTemporary);
                    for (int i = 0; i < linkTemporary.length(); i++) {//4º for interno
                        letra = linkTemporary.charAt(i);
                        if (letra == 'h') {// 7º if interno
                            for (int j = i; j < linkTemporary.length(); j++) {

                                newlink += linkTemporary.charAt(j);

                            }
                            newlink = newlink.replace("!og", "");
                            if (precisaRepassar(newlink)) {
                                newlink = quebraLink(newlink);
                                if (isValid(newlink)) {
                                    return newlink;
                                }
                            } else {
                                if (isValid(newlink)) {
                                    return newlink;
                                }
                            }
                        }//fecha 7º if interno
                    }//fecha 4º for interno
                }//fecha 6º if interno

            }//fecha 2º if interno
            estado = false;
            linkTemporary = "";
            for (int i = 0; i < linkOrig.length(); i++) {// 3º for interno

                letra = linkOrig.charAt(i);
                if (letra == '?') {// 8º if interno

                    for (int j = i + 1; j < linkOrig.length(); j++) {// 5º for interno
                        linkTemporary += linkOrig.charAt(j);

                    }//fecha 5º for interno
                    linkTemporary = linkTemporary.replace(".", "");

                    try {
                        link = HexToChar(linkTemporary);
                    } catch (Exception e) {
                        System.err.println("erro hex 2º");
                        estado = true;
                    }

                    break;
                }//fecha 8º if interno
            }// fecha 3º for interno

            if (link.contains("http") && !estado) {// 9º if interno
                newlink = "";
                for (int i = 0; i < link.length(); i++) {//6º for interno
                    letra = link.charAt(i);

                    if (letra == 'h') {// 10º if interno
                        for (int j = i; j < link.length(); j++) {
                            newlink += link.charAt(j);
                        }
                        newlink = newlink.replace("!og", "");
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    }//fecha 10º if interno
                }//fecha 6º for interno
            }// 9º if interno

            if (link.contains("ptth") && !estado) {//11º if interno
                newlink = "";
                linkTemporary = inverteFrase(link);

                for (int i = 0; i < linkTemporary.length(); i++) {// 7º for interno
                    letra = linkTemporary.charAt(i);

                    if (letra == 'h') {// 12º if interno

                        for (int j = i; j < linkTemporary.length(); j++) {// 8 for interno

                            newlink += linkTemporary.charAt(j);
                        }//fecha 8 for interno
                        newlink = newlink.replace("!og", "");
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    }//fecha 12º if interno
                }//fecha  7º for interno
            }//fecha 11º if interno;
            linkOrig = linkInit;
            link = linkOrig;
            newlink = "";
        }// fecha 1º if externo

//===========================================================================================
        //http://indica.celularbr.com/?http://hotfile.com/dl/97226490/9e96e24/EDUCOSVVSP11.zip.html
        if (linkOrig.contains("?") && !linkOrig.contains("id=") && !linkOrig.contains("url=") && !linkOrig.contains("link=") && !linkOrig.contains("r=http") && !linkOrig.contains("r=ftp")) {
            for (int i = 0; i < linkOrig.length(); i++) {
                letra = linkOrig.charAt(i);
                if (letra == '?') {
                    newlink = "";
                    for (int j = i + 1; j < linkOrig.length(); j++) {
                        newlink += linkOrig.charAt(j);
                    }
                    if (newlink.contains("ptth")) {

                        newlink = inverteFrase(newlink);
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    } else {
                        if (precisaRepassar(newlink)) {
                            newlink = quebraLink(newlink);
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        } else {
                            if (isValid(newlink)) {
                                return newlink;
                            }
                        }
                    }
                }

            }
        }



//===========================================================================================

        //  6º PARTE
        if ((link.contains("url=")) || (link.contains("link=")) || (link.contains("?r=http")) || (link.contains("?r=ftp"))) {
            if (!link.contains("//:ptth")) {
                for (int i = 0; i < link.length(); i++) {
                    letra = link.charAt(i);
                    if (letra == '=') {

                        for (int j = i + 1; j < link.length(); j++) {
                            letra = link.charAt(j);
                            newlink += letra;

                        }

                        break;
                    }

                }
                if (precisaRepassar(newlink)) {
                    newlink = quebraLink(newlink);
                    if (isValid(newlink)) {
                        return newlink;
                    }
                } else {
                    if (isValid(newlink)) {
                        return newlink;
                    }
                }
            }//termina IF interno
        }//termina 1º IF

        //============================================================================
        // 7º PARTE


        if (linkOrig.contains("//:ptth") || linkOrig.contains("//:sptth")) {
            if (linkOrig.contains("=")) {
                for (int i = 0; i < linkOrig.length(); i++) {
                    letra = linkOrig.charAt(i);
                    if (letra == '=') {
                        for (int j = linkOrig.length() - 1; j > i; j--) {

                            letra = linkOrig.charAt(j);
                            newlink += letra;
                        }

                        break;
                    }
                }

                if (precisaRepassar(newlink)) {
                    newlink = quebraLink(newlink);
                    if (isValid(newlink)) {
                        return newlink;
                    }
                } else {
                    if (isValid(newlink)) {
                        return newlink;
                    }
                }
            }

            newlink = inverteFrase(linkOrig);
            if (precisaRepassar(newlink)) {
                newlink = quebraLink(newlink);
                if (isValid(newlink)) {
                    return newlink;
                }
            } else {
                if (isValid(newlink)) {
                    return newlink;
                }
            }
        }

//=================================================================================
        // 8º parte obs:essa parte foi a mais fácil :)


        if (linkOrig.contains("?go!")) {
            linkOrig = linkOrig.replace("?go!", "?down!");
            newlink = linkOrig;

            if (precisaRepassar(newlink)) {
                newlink = quebraLink(newlink);
                if (isValid(newlink)) {
                    return newlink;
                }
            } else {
                if (isValid(newlink)) {
                    return newlink;
                }
            }
        }



//============================================================================================
        //@TODO acrescentar essa url a lista
//http://www.exadownload.com/download/?down!aHR0cDovL3d3dy5sb2NrdXJsLm9yZy9obmtBVUs=        
        if (linkOrig.contains("down!")) {
            linkOrig = linkOrig.replace("down!", "");
            return quebraLink(linkOrig);
        }
//============================================================================================
        // verifica se o link está depois do ultimo igual, porque o inicio do codigo
        //verifica somente se está depois do 1º igual
        newlink = "";
        for (int i = linkOrig.length() - 4; i >= 0; i--) {
            letra = linkOrig.charAt(i);
            if (letra == '=') {
                for (int j = i + 1; j < linkOrig.length(); j++) {
                    newlink += linkOrig.charAt(j);
                }
                break;
            }
        }
        String ltmp = "";
        try {
            ltmp = HexToChar(newlink);
        } catch (Exception e) {
            System.err.println("erro hex 3º");
        }
        if (ltmp.contains("http://")) {
            if (precisaRepassar(ltmp)) {
                ltmp = quebraLink(ltmp);
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            } else {
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            }
        } else if (ltmp.contains("//:ptth")) {
            ltmp = inverteFrase(ltmp);
            if (precisaRepassar(ltmp)) {
                ltmp = quebraLink(ltmp);
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            } else {
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            }
        } else {
            ltmp = newlink;
        }
        ltmp = decode64(newlink);
        if (ltmp.contains("http://")) {
            if (precisaRepassar(ltmp)) {
                ltmp = quebraLink(newlink);
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            } else {
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            }
        } else if (ltmp.contains("//:ptth")) {
            ltmp = inverteFrase(ltmp);
            if (precisaRepassar(ltmp)) {
                newlink = quebraLink(newlink);
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            } else {
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            }
        } else {
            ltmp = newlink;
        }
        try {
            ltmp = decodeAscii(newlink);
        } catch (NumberFormatException e) {
            System.err.println("erro ascii");
        }
        if (ltmp.contains("http://")) {
            if (precisaRepassar(ltmp)) {
                ltmp = quebraLink(newlink);
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            } else {
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            }
        } else if (ltmp.contains("//:ptth")) {
            ltmp = inverteFrase(ltmp);
            if (precisaRepassar(ltmp)) {
                ltmp = quebraLink(ltmp);
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            } else {
                if (isValid(ltmp)) {
                    newlink = ltmp;
                    return newlink;
                }
            }
        } else {
            ltmp = null;
        }


        newlink = "";
//============================================================================================
        // logic crazy puzzle
        int cont = 0;
        letra = '\0';
        ltmp = "";
        newlink = "";
        //link de teste para algoritmo == linkOrig = "http://reidodownload.net/redirect/download2/index.php?id=355807894013570158588780187170019609401289016809476012831194701799499580984684868801684858911701801001576119019887288889388018838121777877472870178121111968987947015898755810141109070978076017709001279902198801787635786898660112870107221793721180110128474848872119477501687014827948458111686878";

        for (int i = linkOrig.length() - 4; i >= 0; i--) {
            letra = linkOrig.charAt(i);
            if (letra == '=' || letra == '?') {
                for (int j = i + 1; j < linkOrig.length(); j++) {
                    if (linkOrig.charAt(j) == '.') {
                        break;
                    }
                    newlink += linkOrig.charAt(j);


                }
                break;
            }
        }

        ltmp = newlink;
        String tmp = "";
        String tmp2 = "";
        do {

//hexadecimal decode inicio
            try {
                tmp = HexToChar(ltmp);
                tmp2 = HexToChar(inverteFrase(ltmp));
                if (!tmp.isEmpty() && tmp.length() > 5 && !tmp.contains("") && !tmp.contains("§") && !tmp.contains("�") && !tmp.contains("")) {
                    ltmp = HexToChar(ltmp);

                } else if (!inverteFrase(tmp2).isEmpty() && inverteFrase(tmp2).length() > 5 && !inverteFrase(tmp2).contains("") && !inverteFrase(tmp2).contains("§") && !inverteFrase(tmp2).contains("�")) {
                    ltmp = HexToChar(inverteFrase(ltmp));

                }
            } catch (NumberFormatException e) {
            }//hexadecimal decode inicio



            //base64 decode inicio
            tmp = decode64(ltmp);
            tmp2 = decode64(inverteFrase(ltmp));
            if (!tmp.contains("�") && !tmp.contains("ޚ")) {
                ltmp = decode64(ltmp);

            } else if (!tmp2.contains("�") && !tmp2.contains("ޚ")) {
                ltmp = decode64(inverteFrase(ltmp));
            }//base64 decode fim



            //ASCII decode inicio
            try {
                tmp = decodeAscii(ltmp);
                tmp2 = decodeAscii(inverteFrase(ltmp));
                if (!tmp.contains("") && !tmp.contains("�") && !tmp.contains("§") && !tmp.contains("½") && !tmp.contains("*") && !tmp.contains("\"") && !tmp.contains("^")) {
                    ltmp = decodeAscii(ltmp);

                } else if (!tmp2.contains("") && !tmp2.contains("�") && !tmp2.contains("§") && !tmp2.contains("½") && !tmp2.contains("*") && !tmp2.contains("\"") && !tmp2.contains("^")) {
                    ltmp = decodeAscii(inverteFrase(ltmp));

                }

            } catch (NumberFormatException e) {
            }//ASCII decode fim


            cont++;
            if (ltmp.contains("http")) {
                newlink = ltmp;

                if (precisaRepassar(newlink)) {
                    newlink = quebraLink(newlink);
                    if (isValid(newlink)) {
                        return newlink;
                    }
                } else {
                    if (isValid(newlink)) {
                        return newlink;
                    }
                }
            } else if (ltmp.contains("ptth")) {
                newlink = inverteFrase(ltmp);

                if (precisaRepassar(newlink)) {
                    newlink = quebraLink(newlink);
                    if (isValid(newlink)) {
                        return newlink;
                    }
                } else {
                    if (isValid(newlink)) {
                        return newlink;
                    }
                }
            }

        } while (!isValid(newlink) && cont <= 20);

        tmp = null;
        tmp2 = null;
        ltmp = null;

//============================================================================================
        //Obtendo o HTML da página e verificando a existencia de JS especifico
        String leitura = "";
        try {
            leitura = readHTML(linkInit);
        } catch (IOException e) {
        }
        leitura = leitura.toLowerCase();
        if (leitura.contains("trocabotao")) {
            newlink = "";
            for (int i = leitura.indexOf("trocabotao"); i < leitura.length(); i++) {
                if (Character.isDigit(leitura.charAt(i))) {
                    int tmpInt = i;
                    while (Character.isDigit(leitura.charAt(tmpInt))) {
                        newlink += leitura.charAt(tmpInt);
                        tmpInt++;
                    }
                    cod = Integer.parseInt(newlink);
                    break;
                }
            }
            if (cod != 0) {
                for (int i = 7; i < linkInit.length(); i++) {
                    letra = linkInit.charAt(i);
                    if (letra == '/') {
                        newlink = linkInit.substring(0, i + 1) + "linkdiscover.php?cod=" + cod;
                        break;
                    }
                }
                DataInputStream dat = null;
                try {
                    URL url = new URL(newlink);
                    InputStream in = url.openStream();
                    dat = new DataInputStream(new BufferedInputStream(in));
                    leitura = "";
                    int dado;
                    while ((dado = dat.read()) != -1) {
                        letra = (char) dado;
                        leitura += letra;
                    }
                    newlink = leitura.replaceAll(" ", "");
                    if (precisaRepassar(newlink)) {
                        newlink = quebraLink(newlink);
                        if (isValid(newlink)) {
                            return newlink;
                        }
                    } else {
                        if (isValid(newlink)) {
                            return newlink;
                        }
                    }
                } catch (MalformedURLException ex) {
                    System.out.println("URL mal formada.");
                } catch (IOException e) {
                } finally {
                    try {
                        if (dat != null) {
                            dat.close();
                        }
                    } catch (IOException e) {
                        System.err.println("Falha ao fechar fluxo.");
                    }
                }

            }

        }
        //@TODO colocar na proxima release note, melhoria no algoritmo
        //realmente preciso dar outro nome pra esse metodo, ficou escroto "precisaRepassar"!
        if (precisaRepassar(linkInit)) {
            if (linkInit.substring(8).contains("http")) {
                newlink = linkInit.substring(linkInit.indexOf("http", 8), linkInit.length());
                if (isValid(newlink)) {
                    return newlink;
                }
            }//@TODO implementar um else compativel aqui
        }

//----------------------------------------------------------------------------------
        //verifica o fonte atras de links usando a bliblioteca de sites
        newlink = "";
        StringBuffer strBuf = null;
        try {
            strBuf = new StringBuffer(readHTML(linkInit));
            for (String tmp3 : getLibrary()) {

                if (strBuf.toString().toLowerCase().contains(tmp3)) {
                    for (int i = strBuf.toString().indexOf(tmp3); i >= 0; i--) {
                        if (strBuf.toString().charAt(i) == '"') {
                            for (int j = i + 1; j < strBuf.length(); j++) {
                                if (strBuf.toString().charAt(j) == '"') {
                                    if (precisaRepassar(newlink)) {
                                        newlink = quebraLink(newlink);
                                        if (isValid(newlink)) {
                                            return newlink;
                                        }
                                    } else {
                                        if (isValid(newlink)) {
                                            return newlink;
                                        }
                                    }
                                } else {
                                    newlink += strBuf.toString().charAt(j);
                                }
                            }
                        }
                    }
                }
            }
        } catch (IOException ex) {
        }

        GUIQuebraLink.isBroken = false; // configura se o link foi quebrado, para a classe
        // GUIQuebraLink saber se deve exibir a menssagem de alerta ou não
        return "Desculpe o link não pode ser quebrado.";

    }

    private static String decode64(String TextoIni) {
        String textFinal = "";
        try {
            String TextoDecript = new String(new BASE64Decoder().decodeBuffer(TextoIni));
            textFinal = TextoDecript;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return textFinal;
    }

    private String inverteFrase(String frase) {
        StringBuffer newfrase = new StringBuffer(frase.length());


        for (int i = frase.length() - 1; i >= 0; i--) {
            newfrase.append(frase.charAt(i));

        }
        return newfrase.toString();
    }

    private static String HexToChar(String hex) throws NumberFormatException {
        char value[] = new char[hex.length() / 2];
        int hexLength = value.length;
        for (int i = 0; i < hexLength; i++) {
            value[i] = (char) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
        }
        return new String(value);
    }
    //@TODO nota: lembrar de dar um nome melhor pra esse metodo

    private boolean precisaRepassar(String link) {
        if (link.contains("lockurl")) {
            return true;
        }
        if (link.length() > 8) {
            if (link.contains("aliancaproject")  || link.substring(8).contains("http") || link.substring(8).contains("ptth")) {
                return true;
            } else {
                return false;
            }

        } else {
            return false;
        }
    }

    private String[] getLibrary() {

        String[] library = {"sharex.xpg", "megaupload.com", "fileserve", "filesonic", "hotfile.com", "uploadstation", "easy-share", "rapidshare", "mediafire", "4shared", "bitroad", "depositfiles", "filebase", "freakshare", "multiupload", "zshare", "2shared", "migre", "ul.to", "uploaded.to", "oron.com", "bitshare", "uploading", "yess.me", "megavideo", "netload", "ziddu", "filebase.to", "wupload.com", "bit.ly", "goo.gl", "up-file.com", "letitbit.net", "badongo.com", "filebase.to", "ezyfile.net", "neo-share.com", "shareflare.net", "filefactory.com", "videobb.com", "castordownloads", "lix.in", "sharingmatrix", "fiberupload", "uploadboost", "ifile", "pieceproject", "zidu", "netload","ul.to", "jumbofiles", "zippyshare", "filefactory", "filerio", "min.us", "ppl.ug", "crocko.com", "uploadjet.net", "azushare.net", "upmirror.com", "zippyshare.com"};
        return library;
    }

    private boolean isValid(String link) {
        for (String tmp : getLibrary()) {
            if (link.toLowerCase().contains(tmp)) {
                validLink = tmp;
                return true;
            }
        }
        return false;
    }

    private String decodeAscii(String ascii) throws NumberFormatException {
//algoritmo de decode sem escape ou caractere marcador criado por mim

        char num = 0;
        int num2 = 0;
        String recebe = "";
        String convertida = "";

        for (int j = 0; j < ascii.length(); j++) {
            num = ascii.charAt(j);

            recebe = recebe + num;
            num2 = Integer.parseInt(recebe);


            //converte uma sequência de caracteres acii para String
            if ((num2 >= 32) && (num2 <= 319)) {
                num = (char) num2;
                convertida += num;
                num2 = 0;
                recebe = "";
            }


        }
        return convertida;
    }

    protected static String readHTML(String link) throws IOException {
        URL url = null;
        try {
            url = new URL(link);
        } catch (MalformedURLException ex) {
            System.err.println("URL mal formada!");
        }

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));

        StringBuffer newData = new StringBuffer();
        String s = "";

        while (null != (s = br.readLine())) {
            newData.append(s);
        }
        br.close();
        /*
        System.out.println(new String(newData));
        
        System.out.println("Resultado: "
        + connection.getResponseCode()
        + "/"
        + connection.getResponseMessage());
         * 
         */
        return newData.toString();
    }

    private static String decodeCifraDeCesar(String link) {

        link = link.replaceAll("025", "a");

        link = link.replaceAll("a56", "b");

        link = link.replaceAll("bA5", "c");

        link = link.replaceAll("Bc7", "d");

        link = link.replaceAll("AdD", "e");

        link = link.replaceAll("ec3", "f");

        link = link.replaceAll("e2d", "g");

        link = link.replaceAll("a2d", "h");

        link = link.replaceAll("ge4", "i");

        link = link.replaceAll("i6A", "j");

        link = link.replaceAll("F7e", "k");

        link = link.replaceAll("kf4", "l");

        link = link.replaceAll("21F", "m");

        link = link.replaceAll("f25", "n");

        link = link.replaceAll("m91", "o");

        link = link.replaceAll("ij5", "p");

        link = link.replaceAll("j32", "q");

        link = link.replaceAll("q56", "r");

        link = link.replaceAll("f0j", "s");

        link = link.replaceAll("f0d", "t");

        link = link.replaceAll("qs0", "u");

        link = link.replaceAll("r02", "v");

        link = link.replaceAll("5fg", "w");

        link = link.replaceAll("ppN", "x");

        link = link.replaceAll("f0C", "y");

        link = link.replaceAll("56s", "z");

        link = link.replaceAll("sx0", ".");

        link = link.replaceAll("x15", "/");

        link = link.replaceAll("x5F", ":");

        link = link.replaceAll("pxw", "?");

        link = link.replaceAll("zc0", "=");


        return link;
    }
}
